package config

import (
	"time"

	"github.com/spf13/viper" // 用于读取配置文件和环境变量的第三方库
)

// 全局配置变量，程序启动时初始化后，其他包可直接引用
// 采用单例模式，确保配置在全程序中唯一且可全局访问
var Conf = &Config{}

// Config 系统总配置结构体
// 包含程序所有核心配置项，使用mapstructure标签实现配置解析映射
type Config struct {
	DB  DBConfig  `mapstructure:"db"`  // 数据库配置，对应配置中的"db"字段
	JWT JWTConfig `mapstructure:"jwt"` // JWT认证配置，对应配置中的"jwt"字段
}

// DBConfig 数据库配置结构体
// 存储数据库连接相关参数
type DBConfig struct {
	// DSN (Data Source Name) 数据库连接字符串
	// 格式：用户名:密码@tcp(地址:端口)/数据库名?参数
	// mapstructure标签指定配置解析时对应的字段名
	DSN string `mapstructure:"dsn"`
}

// JWTConfig JWT认证配置结构体
// 存储JWT生成与验证相关的参数
type JWTConfig struct {
	Secret  string        `mapstructure:"secret"`  // JWT签名密钥，用于生成和验证token
	Expires time.Duration `mapstructure:"expires"` // JWT过期时间，time.Duration类型支持时间单位
}

// Init 初始化配置
// 功能：从环境变量读取配置，若无则使用默认值，最终初始化全局变量Conf
func Init() {
	// 1. 启用自动读取环境变量功能
	// viper会自动将环境变量转换为小写并替换下划线为点，例如BLOG_DB_DSN会映射为blog.db.dsn
	viper.AutomaticEnv()

	// 2. 初始化数据库配置
	// 优先从环境变量BLOG_DB_DSN获取数据库连接字符串
	Conf.DB.DSN = viper.GetString("BLOG_DB_DSN")
	// 若环境变量未设置，则使用默认的本地MySQL连接配置
	if Conf.DB.DSN == "" {
		Conf.DB.DSN = "root:lrx563647@tcp(127.0.0.1:3306)/blog_db?charset=utf8mb4&parseTime=true&loc=Local"
	}

	// 3. 初始化JWT密钥配置
	// 优先从环境变量BLOG_JWT_SECRET获取JWT签名密钥
	Conf.JWT.Secret = viper.GetString("BLOG_JWT_SECRET")
	// 若环境变量未设置，则使用开发环境的临时密钥（生产环境必须通过环境变量设置）
	if Conf.JWT.Secret == "" {
		Conf.JWT.Secret = "blog-jwt-secret-2025-dev" // 生产环境必须替换为环境变量
	}

	// 4. 初始化JWT过期时间配置
	// 从环境变量BLOG_JWT_EXPIRES获取过期时间（小时），转换为time.Duration类型
	Conf.JWT.Expires = time.Duration(viper.GetInt64("BLOG_JWT_EXPIRES")) * time.Hour
	// 若环境变量未设置，则使用默认的24小时过期时间
	if Conf.JWT.Expires == 0 {
		Conf.JWT.Expires = 24 * time.Hour
	}
}
